package com.yeyks.commonReference.append.app.impl;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.IOUtils;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectResult;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.commonReference.append.app.OssService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

@Service
@Slf4j
public class OssServiceImpl implements OssService {

    private static String endpoint = "oss-cn-hangzhou.aliyuncs.com";
    private static String accessKey = "LTAITpv2oyvCJueR";
    private static String accessKeySecret = "FC20WVDv4nHzQ77TQaZBzkgCsBYJB4";
    private static String bucket = "yeyu-kuaisu";
    private OSSClient ossClient;
    private static String prefixUrl = "https://yeyu-kuaisu.oss-cn-hangzhou.aliyuncs.com/";

    public OssServiceImpl() {
        ossClient = new OSSClient(endpoint, accessKey, accessKeySecret);
    }

    @Override
    public String getPrefixUrl() {
        return prefixUrl;
    }

    @Override
    public String uploadImage(InputStream inputStream, String key) {
        PutObjectResult putObjectResult = ossClient.putObject(bucket, key, inputStream);
        return getPrefixUrl() + key;
    }

    /**
     * 上传图片返回url
     *
     * @param userId
     * @param file
     * @return
     */
    @Override
    public String ossUpload(Integer userId, MultipartFile file) {
        try {
            if (!file.isEmpty()) {
                String filename = file.getOriginalFilename();
                String newName = getFileName(FilenameUtils.getExtension(filename));
                String ossKey = null;
                if (userId == null) {
                    ossKey = "Public/" + newName;
                } else {
                    ossKey = "User/" + userId.toString() + "/" + newName;
                }
                if (writeOSS(file.getBytes(), ossKey)) {
                    return prefixUrl + ossKey;
                }
            }
        } catch (Exception e) {
            log.info("文件上传出错{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        throw new ServiceException("文件上传失败");

    }

    /**
     * 上传酒店图片返回url
     *
     * @param hotelId
     * @param file
     * @return
     */
    @Override
    public String uploadHotelImg(String hotelId, MultipartFile file) {
        try {
            if (!file.isEmpty()) {
                String filename = file.getOriginalFilename();
                String newName = getFileName(FilenameUtils.getExtension(filename));
                String ossKey;
                if (hotelId == null) {
                    ossKey = "hotel/" + newName;
                } else {
                    ossKey = "hotel/" + hotelId + "/" + newName;
                }
                if (writeOSSAndBucket(bucket, file.getBytes(), ossKey)) {
                    return prefixUrl + ossKey;
                }
            }
        } catch (Exception e) {
            log.info("酒店图片文件上传出错{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        throw new ServiceException("酒店图片文件上传失败");
    }

    /**
     * 上传房间图片返回url
     *
     * @param hotelId
     * @param roomId
     * @param file
     * @return
     */
    @Override
    public String uploadRoomImg(String hotelId, String roomId, MultipartFile file) {
        try {
            if (!file.isEmpty()) {
                String filename = file.getOriginalFilename();
                String newName = getFileName(FilenameUtils.getExtension(filename));
                String ossKey = "room/" + newName;
                if (null == hotelId && null == roomId) {
                    ossKey = "room/" + newName;
                }
                if (null != roomId && null == hotelId) {
                    ossKey = "room/" + roomId + "/" + newName;
                }
                if (null == roomId && null != hotelId) {
                    ossKey = "room/" + hotelId + "/" + newName;
                }
                if (null != roomId && null != hotelId) {
                    ossKey = "room/" + hotelId + "/" + roomId + "/" + newName;
                }
                if (writeOSSAndBucket(bucket, file.getBytes(), ossKey)) {
                    return prefixUrl + ossKey;
                }
            }
        } catch (Exception e) {
            log.info("房间图片文件上传出错{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        throw new ServiceException("房间图片文件上传失败");
    }

    @Override
    public boolean deleteOSS(String key) {

        try {
            ossClient.deleteObject(bucket, key);
            return true;
        } catch (Exception e) {
            log.info("删除文件异常");
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 通过原始名称获取随机名称的图片名
     */
    private static String getFileName(String ext) {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String name = simpleDateFormat.format(date);
        return name + getSixNumStr() + "." + ext;
    }

    /**
     * 获取六位数字随机数
     */
    private static String getSixNumStr() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }

    @Override
    public byte[] readOSS(String key) {
        InputStream is = null;
        try {
            OSSObject object = null;
            object = ossClient.getObject(bucket, key);
            if (object == null) {
                return null;
            }
            is = object.getObjectContent();
            return IOUtils.readStreamAsByteArray(is);
        } catch (Exception e) {
            return null;
        } finally {
            IOUtils.safeClose(is);
        }
    }

    @Override
    public boolean writeOSS(Object source, String key) {
        return writeOSSAndBucket(bucket, source, key);
    }

    private boolean writeOSSAndBucket(String bucket, Object source, String key) {
        InputStream in = null;
        if (null == source) {
            return false;
        }
        try {
            in = getInputStream(source);
            ossClient.putObject(bucket, key, in);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.safeClose(in);
        }
        return false;
    }

    public String generatePresignedUrl(String key, int expireSeconds) {
        long time = System.currentTimeMillis() + expireSeconds * 1000;
        try {
            URL url = ossClient.generatePresignedUrl(bucket, key, new Date(time));
            return url.toString();
        } catch (Exception e) {
        }
        return null;
    }

    private InputStream getInputStream(Object source) throws FileNotFoundException {
        InputStream in;
        if (source instanceof InputStream) {
            in = (InputStream) source;
        } else if (source instanceof byte[]) {
            in = new ByteArrayInputStream((byte[]) source);
        } else {
            in = new FileInputStream(source.toString());
        }
        if (null == in) {
            throw new RuntimeException("Object转文件流失败，找不到对应类型");
        }
        return in;
    }
}
